package com.guokai2012.util;

import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Consumer;

/**
 * @ClassName TestJTable2
 * @Author guokai2012
 * @Description 表格
 */
public class MainTable extends JTable {
    private Vector<String> colName;
    private Vector<Vector<Object>> rowData;
    private JFrame frame;
    private int initRows = 3;
    private Consumer<MainTable> callBack;
    private SimpleDateFormat sdf;


    public MainTable(Vector<String> colName, Vector<Vector<Object>> rowData, JFrame frame, String sdf) {
        this.colName = colName;
        this.rowData = rowData;
        this.frame = frame;
        this.sdf = new SimpleDateFormat(sdf);
    }

    public void initMainTable() {
        // 给初始化数据，添加 3行默认空白数据。方便录入信息。
        initRowData(this.initRows);
        // 设置表头高度
        setHeaderHeight(5);
        // 设置行高
        setRowHeight(40);
        // 设置单元格 内边距
        setIntercellSpacing(new Dimension(20, 10));
        // 设置 行选中 背景色
        setSelectionBackground(Color.WHITE);
        // 只绘制 水平线 true 绘制， false 不绘制
        setShowHorizontalLines(true);
        // 只 绘制 垂直线  true 绘制，false 不绘制
        setShowVerticalLines(false);
        // 添加单元格编辑监听事件
        modelListener();
    }

    public void setCallBack(Consumer<MainTable> consumer) {
        this.callBack = consumer;
    }

    /**
     * 默认 初始化 表格行数
     */
    private void initRowData(int h) {
        for (int i = 0; i < h; i++) {
            Vector<Object> line = new Vector<Object>() {{
                add(new Boolean(false));
                add(null);
                add(null);
            }};
            this.rowData.add(line);
        }
        /**
         * 利用 匿名类，继承 DefaultTableModel类，然后重写 DefaultTableModel中的 getColumnClass方法。
         * 让该方法返回 其值的 实际 类型。而非统一返回 Object.class。
         * 从而完成 排序处理时 正确排序。
         */
        setModel(new DefaultTableModel(rowData, colName) {
            @Override
            public Class<?> getColumnClass(int columnIndex) {
                Class<?> aClass = Object.class;
                Object value = getValueAt(0, columnIndex);
                if (null != value) {
                    aClass = value.getClass();
                }
                return aClass;
            }
        });
        // 设置单元格样式
        setCellBackGroundColor();
        // 设置 列最小宽度
        setColWidth();
        // 自定义单元格编辑器
        setCellEditor();
        // 设置表头默认排序
        // setSort();
    }


    /**
     * 设置 当 提醒日期超过 提醒时间时，单元格背景颜色
     */
    private void setCellBackGroundColor() {
        /*DefaultTableCellRenderer cellRenderer = new DefaultTableCellRenderer() {
            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
                if (null != value && !"".equals(value)) {
                    try {
                        String tmpV = value.toString();
                        if (column == 0) {
                            Object v2 = getValueAt(row, 1);
                            if (null == v2 || "".equals(v2)) {
                                return cell;
                            }
                            tmpV = v2.toString();
                        }
                        Date parse = sdf.parse(tmpV, new ParsePosition(0));
                        if (System.currentTimeMillis() > parse.getTime()) {
                            cell.setForeground(Color.RED);
                        } else {
                            cell.setForeground(null);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                return cell;
            }
        };*/

        for (int i = 0; i < getColumnCount(); i++) {
            TableColumn column = getColumnModel().getColumn(i);
            column.setCellRenderer(new MyTableCellRenderer());
        }

        TableColumn aColumn = getColumnModel().getColumn(0);
        aColumn.setCellEditor(getDefaultEditor(Boolean.class));
        aColumn.setCellRenderer(getDefaultRenderer(Boolean.class));
    }

    /**
     * 设置 表头排序
     */
    private void setSort() {
        // 设置 指定列 自动排序  -- 排序需要 表头为显示状态，否则无法排序
        TableRowSorter<TableModel> sorter = new TableRowSorter<>(getModel());
        ArrayList<RowSorter.SortKey> sortKeys = new ArrayList<>();
        // 添加指定列的排序规则：1代表要排序的列，ASCENDING -> asc, DESCENDING -> desc, UNSORTED 不排序
        RowSorter.SortKey sortKey = new RowSorter.SortKey(1, SortOrder.ASCENDING);
        sortKeys.add(sortKey);
        sorter.setSortKeys(sortKeys);
        setRowSorter(sorter);
    }

    /**
     * 单元格 触发事件
     */
    private void modelListener() {

    }

    /**
     * 设置表头的高度
     */
    private void setHeaderHeight(int height) {
        JTableHeader header = getTableHeader();
        Dimension headerSize = header.getPreferredSize();
        headerSize.height += height;
        header.setPreferredSize(headerSize);
    }

    /**
     * 设置 列 的最小宽度
     */
    private void setColWidth() {
        // 获取 frame窗口的宽度，然后根据frame宽度，进行计算2个单元格宽度占比。去掉 内边距
        int col1w = Math.round(this.frame.getWidth() * 0.7f) - (getIntercellSpacing().width * 4) - 33;
        // 循环每一列
        for (int i = 0; i < getColumnCount(); i++) {
            // 根据 列模型，获取指定index列的 TableColumn
            TableColumn tc = getColumnModel().getColumn(i);
            // 根据列index获取列名，通过列名，获取 table列对象
            // 设置 第一列的 最小宽度。
            if (i == 0) {
                tc.setMaxWidth(33);
            }
            if (i == 1) {
                tc.setMinWidth(col1w);
            }
        }
    }

    /**
     * 自定表格单元格 编辑器
     */
    private void setCellEditor() {
        JCheckBox checkBox = new JCheckBox();
        checkBox.setName("check");
        checkBox.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                setCellBackGroundColor();
            }
        });
        checkBox.setBorder(BorderFactory.createEmptyBorder());
        setDefaultCellEditor(checkBox, 0);

        // 生成 文本输入框
        JTextField taskText = new JTextField();
        taskText.setName("task");
        // 设置 文本框 无 边框
        taskText.setBorder(BorderFactory.createEmptyBorder());
        taskText.addFocusListener(new FocusAdapter() {
            @Override
            public void focusLost(FocusEvent e) {
                commitTask(e);
            }
        });
        setDefaultCellEditor(taskText, 1);

        /**
         * 提醒 时间
         */
        DateTimePicker dateTimePicker = new DateTimePicker(sdf.toPattern(), 200, 200);
        JTextField timeText = new JTextField();
        timeText.setName("time");
        timeText.setBorder(BorderFactory.createEmptyBorder());
        timeText.setEnabled(false);
        MainTable self = this;
        dateTimePicker.setTimeEnable(true).changeDateEvent(new Consumer<DateTimePicker>() {
            @Override
            public void accept(DateTimePicker o) {
                if (null != self.callBack) {
                    self.callBack.accept(self);
                    self.setCellBackGroundColor();
                }
            }
        }).register(timeText);
        setDefaultCellEditor(timeText, 2);
    }

    /**
     * 设置 Cell的编辑器
     */
    private void setDefaultCellEditor(JComponent comp, int columnIndex) {
        // 初始化 一个 默认的 Cell编辑组件
        DefaultCellEditor cellEditor;
        if (comp instanceof JTextField) {
            cellEditor = new DefaultCellEditor((JTextField) comp);
        } else if (comp instanceof JCheckBox) {
            cellEditor = new DefaultCellEditor((JCheckBox) comp);
        } else {
            return;
        }
        // 设置组件 开启
        cellEditor.getComponent().setEnabled(true);
        // 设置 组件可焦距
        cellEditor.getComponent().setFocusable(true);
        // 设置 Cell编辑器 开启编辑的 点击次数
        cellEditor.setClickCountToStart(1);
        // 给 table 中指定列设置 Cell编辑器【如果是，所有列需要设置，则循环一下。】
        getColumnModel().getColumn(columnIndex).setCellEditor(cellEditor);
    }

    /**
     * 确认数据，并刷新表格数据
     */
    private void commitTask(FocusEvent e) {
        JTextField taskText = (JTextField) e.getSource();
        if ("task".equals(taskText.getName()) && !"".equals(taskText.getText())) {
            Iterator<Vector<Object>> iterator = this.rowData.iterator();
            while (iterator.hasNext()) {
                Vector<Object> next = iterator.next();
                Object o = next.get(1);
                if (null == o || "".equals(o)) {
                    iterator.remove();
                }
            }
            initRowData(this.initRows);
            if (null != this.callBack) {
                this.callBack.accept(this);
            }
        }
    }

    private class MyTableCellRenderer extends DefaultTableCellRenderer {
        private boolean isCheck;

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            this.setBorder(null);
            if (null != value && !"".equals(value) && column > 0) {
                try {
                    String tmpV = value.toString();
                    if (column == 1) {
                        Object v2 = getValueAt(row, 2);
                        if (null == v2 || "".equals(v2)) {
                            return cell;
                        }
                        tmpV = v2.toString();
                    }
                    Date parse = sdf.parse(tmpV, new ParsePosition(0));
                    if (System.currentTimeMillis() > parse.getTime()) {
                        cell.setForeground(Color.RED);
                    } else {
                        cell.setForeground(null);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else if (column == 0) {
                System.out.println(value);
                isCheck = isSelected;
            }
            return cell;
        }

        @Override
        public void paint(Graphics g) {
            super.paint(g);
            System.out.println(isCheck);
            if (isCheck) {
                Graphics2D g2d = (Graphics2D) g;
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                g2d.setPaint(Color.BLACK);
                g2d.setStroke(new BasicStroke(.5f));
                int i = getHeight() / 2;
                g2d.drawLine(40, i, getWidth(), i);
            }
        }
    }
}
